package com.turtle3d.visualizator;

import javax.media.j3d.Shape3D;
import javax.vecmath.Point3f;

import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;

public class MyCone extends Shape3D
{
	
	public MyCone(float height, float radius){
		createGeometry(height, radius, radius, 16);		
	}
	
	public MyCone(float height, float radius, int halfPointCount){
		createGeometry(height, radius, radius, halfPointCount);		
	}
	
	public MyCone(float height, float radius1, float radius2, int halfPointCount){
		createGeometry(height, radius1, radius2, halfPointCount);
	}
	
	public MyCone(float height, float radius1, float radius2, int halfPointCount, boolean bottom){
		createGeometry(height, radius1, radius2, halfPointCount);
		if(bottom)
			createBottom(radius1, halfPointCount);
	}
	
	private void createBottom(float radius, int halfPointCount){
		
		Point3f middleLower = new Point3f(0,0,0);
		Point3f lower[] = new Point3f[halfPointCount];
		
		for(int i=0;i<halfPointCount;i++){
			double x = Math.sin(i*2*Math.PI/halfPointCount);
			double y = Math.cos(i*2*Math.PI/halfPointCount);
			
			lower[i] = new Point3f((float)x*radius,0,(float)y*radius);								
		}
		
		Point3f points[] = new Point3f[halfPointCount*3];
		
		//bottom
		for(int i=0;i<halfPointCount;i++){
			if(i<halfPointCount-1){
				points[3*i] = middleLower;
				points[3*i+1] = lower[i+1];
				points[3*i+2] = lower[i];
			}
			else{
				points[3*i] = middleLower;
				points[3*i+1] = lower[0];
				points[3*i+2] = lower[i];
			}
		}
		
		int[] stripCounts = new int[halfPointCount];
		for(int i=0;i<halfPointCount;i++)
			stripCounts[i] = 3;
		
		int[] contourCount = new int[halfPointCount];
		for(int i=0;i<halfPointCount;i++)
			contourCount[i] = 1;
		
		GeometryInfo gInf = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);

		gInf.setCoordinates(points);
		gInf.setStripCounts(stripCounts);
		gInf.setContourCounts(contourCount);
		
		NormalGenerator ng = new NormalGenerator();
		ng.setCreaseAngle((float) Math.toRadians(45));
		ng.generateNormals(gInf);
		this.addGeometry(gInf.getGeometryArray());
		
		
	}
	
	private void createGeometry(float height, float radius1, float radius2, int halfPointCount){
		
		Point3f lower[] = new Point3f[halfPointCount];
		Point3f upper[] = new Point3f[halfPointCount];
		
		for(int i=0;i<halfPointCount;i++){
			double x = Math.sin(i*2*Math.PI/halfPointCount);
			double y = Math.cos(i*2*Math.PI/halfPointCount);
			
			lower[i] = new Point3f((float)x*radius1,0,(float)y*radius1);
			upper[i] = new Point3f((float)x*radius2,height,(float)y*radius2);						
		}
				
		//per polygon
		Point3f points[] = new Point3f[halfPointCount*4];				
		for(int i=0;i<halfPointCount;i++){
			if(i<halfPointCount-1){
				points[4*i] = lower[i];
				points[4*i+1] = lower[i+1];
				points[4*i+2] = upper[i+1];
				points[4*i+3] = upper[i];
			} else{
				//last poly
				points[4*i] = lower[i];
				points[4*i+1] = lower[0];
				points[4*i+2] = upper[0];
				points[4*i+3] = upper[i];
			}
		}
              
		int[] stripCounts = new int[halfPointCount];
		for(int i=0;i<halfPointCount;i++)
			stripCounts[i] = 4;
		
		int[] contourCount = new int[halfPointCount];
		for(int i=0;i<halfPointCount;i++)
			contourCount[i] = 1;
		
        /*points[0] = lower[0];
        points[1] = lower[1];
        points[2] = upper[1];
        points[3] = upper[0];
        
        points[4] = lower[1];
        points[5] = lower[2];
        points[6] = upper[2];
        points[7] = upper[1];        
        
        int[] stripCounts = new int[2];
		stripCounts[0] = 4;
		stripCounts[1] = 4;
		
		int[] contourCount = new int[2];
		contourCount[0] = 1;
		contourCount[1] = 1;*/
		
		GeometryInfo gInf = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);

		gInf.setCoordinates(points);
		gInf.setStripCounts(stripCounts);
		gInf.setContourCounts(contourCount);
		
		NormalGenerator ng = new NormalGenerator();
		ng.setCreaseAngle((float) Math.toRadians(45));
		ng.generateNormals(gInf);
		this.setGeometry(gInf.getGeometryArray());
     
		
	}
}
